#include <QCoreApplication>
#include <QThread>
#include <iostream>
#include <string>

class ConsoleReader : public QThread {
    Q_OBJECT

public:
    void run() override {
        char ch;
        while (true) {
            std::cin >> ch;
            emit keyPressed(ch);
        }
    }

signals:
    void keyPressed(char key);
};

class MyApp : public QObject {
    Q_OBJECT

public:
    int factorial(int n)
    {
        if(n == 0 || n == 1) {return 1;}
        return n*factorial(n-1);
    }

public slots:
    void handleKeyPress(char key) {
        if (key == 'q') {
            std::cout << "Key 'q' pressed. Exiting..." << std::endl;
            QCoreApplication::quit();
        } else {
            std::cout << "Key '" << key << "' pressed." << std::endl;
            try {
                std::string str;
                str += key; // Append the character to the string
                int num = std::stoi(str);
                std::cout << "num=" << factorial(num) << std::endl;
            }
            catch(std::invalid_argument e)
            {
                std::cout << "Exception:" << e.what() << std::endl;
            }
        }
    }
};

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);

    ConsoleReader consoleReader;
    MyApp myApp;

    std::cout << "Staring QConsole ..." << std::endl;
    QObject::connect(&consoleReader, &ConsoleReader::keyPressed, &myApp, &MyApp::handleKeyPress);

    consoleReader.start();

    return app.exec();
}

#include "main.moc"